from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
from aijia_rental.utils.views import LoginRequiredMixin
# Create your views here.
from django.views import View

from libs.captcha.captcha import captcha
from django_redis import get_redis_connection

import json

from django import http
import logging

from django.contrib.auth import login, authenticate

from lishiliang.models import User
logger = logging.getLogger('diango')
from celery_tasks.sms.tasks import sms
import random
import re
from django.contrib.auth import logout
import base64

class SmsVerification(View):
    # 短信验证
    def get(self, request):

        cur_uuid = request.GET.get('cur')


        # 生成验证
        # 1.调用工具类 captcha 生成图形验证码
        text, image = captcha.generate_captcha()

        # 2.链接 redis, 获取链接对象
        redis_conn = get_redis_connection('verify_code')

        # 3保存数据到 redis
        redis_conn.setex('img_%s' % cur_uuid, 300, text)

        # 4.返回(图片)
        return HttpResponse(image,
                            content_type='image/jpg')

class SMSCodeView(View):

    def post(self, request):

        # 获取短信验证
        # 检查是否频发发送
        # 1.接受参数
        dict_data = json.loads(request.body.decode())
        mobile = dict_data.get("mobile")
        image_code_id = dict_data.get("id")
        image_code = dict_data.get("text")

        redis_conn = get_redis_connection('verify_code')

        # 判断手机号是否存在
        send_flag = redis_conn.get('send_flag_%s' % mobile)
        if send_flag:
            return http.JsonResponse({'code': 400,
                                      'errmsg': '发送短信过于频繁'})

        # 2.检验
        if not all([mobile, image_code, image_code_id]):
            return http.JsonResponse({'code': 400,
                                      'errmsg': '缺少必传参数'})


        # 提取图形验证码
        image_code_server = redis_conn.get('img_' + image_code_id)

            # 图形验证码不存在或者过期
        if image_code_server is None:
            return http.JsonResponse({'code': 400,
                                      'errmsg': '图形验证码失效'})

        # 删除图形验证码，避免恶意测试图形验证码
        try:
            redis_conn.delete('img_%d' % image_code_id)
        except Exception as e:
            logger.error(e)

        # 对比图形验证码，转换小写

        image_code_server = image_code_server.decode()
        if image_code.lower() != image_code_server.lower():
            return http.JsonResponse({'code': 400,
                                      'errmsg': '输入图形验证码有误'})
        # 生成短信验证吗：6位随机数字
        sms_code = '%06d' % random.randint(0, 999999)
        logger.info(sms_code)
        print(sms_code)

        pl = redis_conn.pipeline()
        pl.setex('sms_%s' % mobile, 300, sms_code)
        pl.setex('send_flag_%s' % mobile, 60, 1)
        pl.execute()

        # CCP().send_template_sms(mobile, [sms_code, 5], 1)
        # ccp_send_sms_code.delay(mobile, sms_code)

        return http.JsonResponse({'errno': 0,
                                  'errmsg': '发送短信成功'})
class RegisterView(View):
    def post(self, request):
        # 接受参数
        dict = json.loads(request.body.decode())
        mobile = dict.get('mobile')
        phonecode = dict.get('phonecode')
        password = dict.get('password')

        # 2.校验(整体)
        if not all([mobile, password, mobile]):
            return http.JsonResponse({'errno': 400,
                                      'errmsg': '缺少必传参数'})

        # 3.mobile检验
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.JsonResponse({'errno': 400,
                                      'errmsg': 'mobile格式有误'})

        # 4.password检验
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return http.JsonResponse({'errno': 400,
                                      'errmsg': 'password格式有误'})


        # 7.sms_code检验 (链接redis数据库)
        redis_conn = get_redis_connection('verify_code')

        # 8.从redis中取值
        sms_code_server = redis_conn.get('sms_%s' % mobile)

        # 9.判断该值是否存在
        if not sms_code_server:
            return http.JsonResponse({'errno': 400,
                                      'errmsg': '短信验证码过期'})
        # 10.把redis中取得值和前端发的值对比
        if phonecode != sms_code_server.decode():
            return http.JsonResponse({'errno': 400,
                                      'errmsg': '验证码有误'})

        try:
            user = User.objects.create_user(password=password,
                                            mobile=mobile,
                                            username=mobile),
        except Exception as e:
            return http.JsonResponse({'errno': 400,
                                   'errmsg': '保存到数据库出错'})


        login(request, user)



        # 13.拼接json返回
        return JsonResponse({'errno': '0',
                                  'errmsg': '注册成功'})
class LoginView1(View):
    def get(self, request):
        # 1.接收参数
        dict = json.loads(request.body.decode())
        username = dict.get('mobile')
        password = dict.get('password')

        # 验证
        if not all([username, password]):
            return JsonResponse({'errno': 400,
                                 'errmsg': '缺少必传参数'})

        # 验证是否能登录
        user = authenticate(username=username,
                            password=password)

        # 判断是否为空
        if  user is None:
            return JsonResponse({'errno':400,
                                 'errmsg':'用户名或者密码错误'})
        # 状态保持
        login(request, user)
        # 返回
        return http.JsonResponse({'errno':'0',
                            'errmsg':'登录成功'})

class LoginView(View):


    def get(self, request):
        user = request.user
        if user.is_authenticated:

            data = {
                "name": user.mobile,
                'user_id':user.id

            }
            return JsonResponse({"errno": 0,
                                 "errmsg": "Ok",
                                 "data": data})
        else:
            return JsonResponse({"errno": 4104,
                                 "errmsg": "未登录"})


    def post(self, request):
        # 1.接收参数
        dict = json.loads(request.body.decode())
        username = dict.get('mobile')
        password = dict.get('password')

        # 验证
        if not all([username, password]):
            return JsonResponse({'errno': 400,
                                 'errmsg': '缺少必传参数'})

        # 验证是否能登录
        user = authenticate(username=username,
                            password=password)


        # 判断是否为空
        if  user is None:
            return JsonResponse({'errno':400,
                                 'errmsg':'用户名或者密码错误'})
        # 状态保持
        login(request, user)
        # 返回
        return JsonResponse({'errno':'0',
                            'errmsg':'登录成功'})


    def delete(self, request):
        """实现退出登录逻辑"""

        # 清理 session
        logout(request)

        # 创建 response 对象.
        response = JsonResponse({'errno':0,
                                 'errmsg':'ok'})

        # 调用对象的 delete_cookie 方法, 清除cookie
        response.delete_cookie('username')

        # 返回响应
        return response



class Userauthentication(LoginRequiredMixin, View):
    # 用户显示
    def get(self, request):

        data = {
            'real_name': request.user.real_name,
            'id_card': request.user.id_card,
        }

        return http.JsonResponse({'errno':'0',
                             'errmsg':'ok',
                             'data':data})
    # 用户认证
    def post(self, request ):

        dict_data = json.loads(request.body.decode())
        real_name = dict_data.get('real_name')
        id_card = dict_data.get('id_card')

        if not all([real_name, id_card]):
            return JsonResponse({'errno':400,
                                 'errmsg':'缺少参数'})

        Errors = ['验证通过!', '身份证号码位数不对!',
                  '身份证号码出生日期超出范围或含有非法字符!',
                  '身份证号码校验错误!', '身份证地区非法!']
        # 各个地区的身份证前两位
        area = {"11": "北京", "12": "天津", "13": "河北", "14": "山西",
                "15": "内蒙古", "21": "辽宁", "22": "吉林", "23": "黑龙江",
                "31": "上海", "32": "江苏", "33": "浙江", "34": "安徽", "35": "福建",
                "36": "江西", "37": "山东", "41": "河南", "42": "湖北", "43": "湖南",
                "44": "广东", "45": "广西", "46": "海南", "50": "重庆", "51": "四川",
                "52": "贵州", "53": "云南", "54": "西藏", "61": "陕西", "62": "甘肃",
                "63": "青海", "64": "宁夏", "65": "新疆", "71": "台湾", "81": "香港",
                "82": "澳门", "91": "国外"}
        idcard = str(id_card)  # 将idcard转为string类型
        idcard = idcard.strip()  # 默认删除空白符
        idcard_list = list(idcard)  # 将idcard 放入列表中
        idcard_brith = idcard[6:14]  # 生日字段
        idcard_sex = idcard[14:17]  # 性别字段
        year = idcard_brith[0:4]  # 年
        month = idcard_brith[4:6]  # 月
        day = idcard_brith[6:8]  # 日
        # 地区校验，验证输入的前两位
        if (not area[(idcard)[0:2]]):
            print(Errors[4])
        # 18位身份号码检测
        elif (len(idcard) == 18):
            # 出生日期的合法性检查
            if (int(idcard[6:10]) % 4 == 0 or (int(idcard[6:10]) % 100 == 0 and int(idcard[6:10]) % 4 == 0)):
                # //闰年出生日期的合法性正则表达式
                ereg = re.compile(
                    '[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$')
            else:
                # //平年出生日期的合法性正则表达式
                ereg = re.compile(
                    '[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$')
            # //测试出生日期的合法性
            if (re.match(ereg, idcard)):
                # //计算校验位
                S = (int(idcard_list[0]) + int(idcard_list[10])) * 7 + \
                    (int(idcard_list[1]) + int(idcard_list[11])) * 9 + \
                    (int(idcard_list[2]) + int(idcard_list[12])) * 10 + \
                    (int(idcard_list[3]) + int(idcard_list[13])) * 5 + \
                    (int(idcard_list[4]) + int(idcard_list[14])) * 8 + \
                    (int(idcard_list[5]) + int(idcard_list[15])) * 4 + \
                    (int(idcard_list[6]) + int(idcard_list[16])) * 2 + \
                    int(idcard_list[7]) * 1 + int(idcard_list[8]) * 6 + \
                    int(idcard_list[9]) * 3
                Y = S % 11  # 求余
                JYM = "10X98765432"
                M = JYM[Y]  # 判断校验位
                if (M == idcard_list[17]):  # 检测ID的校验位
                    if int(idcard_sex) % 2 == 0:
                        pass
                    else:
                        pass
                else:
                    return http.JsonResponse({"errno": 400,
                                              "errmsg": "省份证错误"})
            else:
                return http.JsonResponse({"errno": 400,
                                          "errmsg": "省份证错误"})
        else:
            return http.JsonResponse({"errno": 400,
                                      "errmsg": "省份证错误"})





        print(real_name, id_card)
        try:

            request.user.real_name = real_name
            request.user.id_card = id_card
            request.user.save()

        except Exception as e:
            logger.error(e)
            return http.JsonResponse({"errno": 400,
                                      "errmsg": "数据保存失败"})

        return http.JsonResponse({"errno": 0 ,
                                  "errmsg": '保存成功'})



